/**
 * 规则引擎
 * 负责生成、应用和管理 Whistle 代理规则
 */
class RuleEngine {
  constructor(server, dataStorage) {
    this.server = server;
    this.dataStorage = dataStorage;
    this.rulePrefix = '# Switcher3 Plugin Rules';
    this.activeRules = new Map(); // 存储当前激活的规则 projectId -> rules
  }

  /**
   * 初始化规则引擎
   */
  init() {
    console.log('[Switcher3] 规则引擎初始化');
    
    // 确保规则前缀在Whistle规则中存在
    this.ensureRulesSection();
  }

  /**
   * 确保Whistle规则中有我们的规则区域
   */
  ensureRulesSection() {
    try {
      console.log('[Switcher3] 初始化规则区域');
      
      // 获取当前规则
      let currentRules = '';
      if (this.server && this.server.rules && typeof this.server.rules.get === 'function') {
        currentRules = this.server.rules.get() || '';
      }
      
      // 如果没有插件规则区域，添加一个
      if (!currentRules.includes(this.rulePrefix)) {
        const newRules = currentRules + '\n\n' + this.rulePrefix + '\n';
        
        if (this.server && this.server.rules && typeof this.server.rules.set === 'function') {
          this.server.rules.set(newRules);
          console.log('[Switcher3] 规则区域初始化完成');
        }
      } else {
        console.log('[Switcher3] 规则区域已存在');
      }
    } catch (error) {
      console.error('[Switcher3] 初始化规则区域失败:', error);
    }
  }

  /**
   * 激活指定项目的环境
   */
  async activateEnvironment(projectId, environment) {
    try {
      if (!projectId || !environment) {
        throw new Error('项目ID和环境不能为空');
      }

      const project = this.dataStorage.getProject(projectId);
      if (!project) {
        throw new Error(`项目不存在: ${projectId}`);
      }

      // 获取环境配置
      let configContent = '';
      let environmentName = '';

      if (environment === 'test') {
        configContent = project.environments.test;
        environmentName = '测试环境';
      } else if (environment === 'production') {
        configContent = project.environments.production;
        environmentName = '生产环境';
      } else if (environment.startsWith('custom:')) {
        const ruleId = environment.substring(7);
        const rule = project.customRules.find(r => r.id === ruleId);
        if (!rule) {
          throw new Error(`自定义规则不存在: ${ruleId}`);
        }
        configContent = rule.value;
        environmentName = `自定义规则: ${rule.label}`;
      } else {
        throw new Error(`无效的环境类型: ${environment}`);
      }

      if (!configContent || !configContent.trim()) {
        throw new Error(`${environmentName}配置为空`);
      }

      // 先停用当前项目的规则
      await this.deactivateEnvironment(projectId);

      // 生成新的规则
      const rules = this.generateRules(project, environment, configContent, environmentName);

      // 应用规则到Whistle
      await this.applyRules(projectId, rules);

      console.log(`[Switcher3] 激活项目 ${project.name} 的 ${environmentName}`);
      
      return {
        success: true,
        rules: rules
      };
    } catch (error) {
      console.error('[Switcher3] 激活环境失败:', error);
      throw error;
    }
  }

  /**
   * 停用指定项目的环境
   */
  async deactivateEnvironment(projectId) {
    try {
      if (!projectId) {
        throw new Error('项目ID不能为空');
      }

      const project = this.dataStorage.getProject(projectId);
      if (!project) {
        throw new Error(`项目不存在: ${projectId}`);
      }

      // 移除项目的规则
      await this.removeRules(projectId);

      console.log(`[Switcher3] 停用项目 ${project.name} 的环境`);
      
      return {
        success: true
      };
    } catch (error) {
      console.error('[Switcher3] 停用环境失败:', error);
      throw error;
    }
  }

  /**
   * 生成Whistle规则
   */
  generateRules(project, environment, configContent, environmentName) {
    const timestamp = new Date().toISOString();
    let rules = [];

    // 添加规则头部注释
    rules.push(`# 项目: ${project.name}`);
    rules.push(`# 环境: ${environmentName}`);
    rules.push(`# 激活时间: ${timestamp}`);
    rules.push(`# 项目ID: ${project.id}`);
    rules.push('');

    // 解析配置内容并生成规则
    const configLines = configContent.split('\n');
    
    for (let line of configLines) {
      line = line.trim();
      
      // 跳过空行和注释行
      if (!line || line.startsWith('#')) {
        if (line) {
          rules.push(line); // 保留用户的注释
        }
        continue;
      }

      // 解析域名映射规则（用户输入格式：IP地址 域名）
      const parts = line.split(/\s+/);
      if (parts.length >= 2) {
        const target = parts[0];  // IP地址
        const domain = parts[1];  // 域名
        
        // 生成Whistle规则格式（Whistle格式：域名 IP地址）
        const whistleRule = `${domain} ${target}`;
        rules.push(whistleRule);
      }
    }

    rules.push(''); // 规则结尾空行

    return rules;
  }

  /**
   * 应用规则到Whistle
   */
  async applyRules(projectId, rules) {
    try {
      console.log(`[Switcher3] 开始应用规则，项目ID: ${projectId}`);
      console.log(`[Switcher3] 规则内容:`, rules);
      
      // 获取当前Whistle规则
      let currentRules = '';
      try {
        if (this.server && this.server.rules && typeof this.server.rules.get === 'function') {
          currentRules = this.server.rules.get() || '';
          console.log(`[Switcher3] 获取到现有规则，长度: ${currentRules.length}`);
        } else {
          console.log(`[Switcher3] 无法获取现有规则，从空开始`);
        }
      } catch (error) {
        console.log(`[Switcher3] 获取规则失败，使用空字符串:`, error.message);
      }
      
      // 移除旧的项目规则
      const cleanRules = this.removeProjectRulesFromText(currentRules, projectId);
      console.log(`[Switcher3] 清理后规则长度: ${cleanRules.length}`);
      
      // 构建新的完整规则
      let newRules = cleanRules;
      
      // 确保有插件规则区域
      if (!newRules.includes(this.rulePrefix)) {
        newRules += '\n\n' + this.rulePrefix + '\n';
      }
      
      // 添加新规则到插件区域
      const rulesSections = newRules.split(this.rulePrefix);
      if (rulesSections.length >= 2) {
        // 插件区域存在，在其中添加规则
        const beforeSection = rulesSections[0];
        const afterSection = rulesSections.slice(1).join(this.rulePrefix);
        newRules = beforeSection + this.rulePrefix + '\n' + 
                  rules.join('\n') + '\n' + afterSection;
      } else {
        // 直接添加到末尾
        newRules += rules.join('\n') + '\n';
      }
      
      console.log(`[Switcher3] 最终规则文本:`, newRules);
      
      // 写入规则到Whistle
      try {
        if (this.server && this.server.rules && typeof this.server.rules.set === 'function') {
          this.server.rules.set(newRules);
          console.log(`[Switcher3] 成功写入规则到Whistle`);
          
          // 验证写入
          const verifyRules = this.server.rules.get() || '';
          console.log(`[Switcher3] 验证：规则写入后长度为 ${verifyRules.length}`);
          
          // 缓存激活的规则
          this.activeRules.set(projectId, rules);
          
          return true;
        } else {
          throw new Error('Whistle rules API不可用');
        }
      } catch (writeError) {
        console.error(`[Switcher3] 写入规则失败:`, writeError);
        
        // fallback: 尝试其他可能的API
        if (this.server && typeof this.server.setRules === 'function') {
          console.log(`[Switcher3] 尝试备用API: server.setRules`);
          this.server.setRules(newRules);
          this.activeRules.set(projectId, rules);
          return true;
        }
        
        throw writeError;
      }
      
    } catch (error) {
      console.error('[Switcher3] 应用规则失败:', error);
      throw error;
    }
  }

  /**
   * 从Whistle中移除指定项目的规则
   */
  async removeRules(projectId) {
    try {
      console.log(`[Switcher3] 开始移除项目规则，项目ID: ${projectId}`);
      
      // 获取当前Whistle规则
      let currentRules = '';
      if (this.server && this.server.rules && typeof this.server.rules.get === 'function') {
        currentRules = this.server.rules.get() || '';
        console.log(`[Switcher3] 获取到当前规则，长度: ${currentRules.length}`);
      } else {
        console.log(`[Switcher3] 无法获取当前规则`);
        return true;
      }
      
      // 移除项目规则
      const newRules = this.removeProjectRulesFromText(currentRules, projectId);
      console.log(`[Switcher3] 移除后规则长度: ${newRules.length}`);
      
      // 应用到Whistle
      if (this.server && this.server.rules && typeof this.server.rules.set === 'function') {
        this.server.rules.set(newRules);
        console.log(`[Switcher3] 成功移除项目规则`);
        
        // 验证移除
        const verifyRules = this.server.rules.get() || '';
        console.log(`[Switcher3] 验证：移除后规则长度为 ${verifyRules.length}`);
      }
      
      // 从缓存中移除
      this.activeRules.delete(projectId);
      
      console.log(`[Switcher3] 从Whistle中移除项目 ${projectId} 的规则`);
      
      return true;
    } catch (error) {
      console.error('[Switcher3] 移除规则失败:', error);
      throw error;
    }
  }

  /**
   * 从规则文本中移除指定项目的规则
   */
  removeProjectRulesFromText(rulesText, projectId) {
    const lines = rulesText.split('\n');
    const filteredLines = [];
    let inProjectSection = false;
    let projectSectionDepth = 0;

    for (let i = 0; i < lines.length; i++) {
      const line = lines[i];
      
      // 检查是否是项目规则的开始
      if (line.includes(`# 项目ID: ${projectId}`)) {
        inProjectSection = true;
        projectSectionDepth = 0;
        
        // 回退并移除此项目的所有注释行
        while (filteredLines.length > 0) {
          const lastLine = filteredLines[filteredLines.length - 1];
          if (lastLine.trim().startsWith('#') || lastLine.trim() === '') {
            filteredLines.pop();
          } else {
            break;
          }
        }
        continue;
      }
      
      if (inProjectSection) {
        // 如果遇到下一个项目标识或者连续空行，结束当前项目区域
        if (line.includes('# 项目:') && !line.includes(`# 项目: ${projectId}`) ||
            (line.trim() === '' && projectSectionDepth > 2)) {
          inProjectSection = false;
          projectSectionDepth = 0;
        } else if (line.trim() === '') {
          projectSectionDepth++;
        } else {
          projectSectionDepth = 0;
        }
        
        if (inProjectSection) {
          continue; // 跳过项目规则行
        }
      }
      
      filteredLines.push(line);
    }

    return filteredLines.join('\n');
  }

  /**
   * 获取当前激活的规则
   */
  getActiveRules() {
    const result = [];
    
    for (const [projectId, rules] of this.activeRules.entries()) {
      const project = this.dataStorage.getProject(projectId);
      if (project) {
        result.push({
          projectId: projectId,
          projectName: project.name,
          environment: project.activeEnvironment,
          rules: rules
        });
      }
    }
    
    return result;
  }

  /**
   * 获取指定项目的激活规则
   */
  getProjectRules(projectId) {
    const rules = this.activeRules.get(projectId);
    if (!rules) {
      return null;
    }

    const project = this.dataStorage.getProject(projectId);
    if (!project) {
      return null;
    }

    return {
      projectId: projectId,
      projectName: project.name,
      environment: project.activeEnvironment,
      rules: rules
    };
  }

  /**
   * 清除所有插件规则
   */
  async clearAllRules() {
    try {
      // 获取当前Whistle规则
      let currentRules = this.server.rules.get() || '';
      
      // 移除所有项目规则
      for (const projectId of this.activeRules.keys()) {
        currentRules = this.removeProjectRulesFromText(currentRules, projectId);
      }
      
      // 应用到Whistle
      this.server.rules.set(currentRules);
      
      // 清空缓存
      this.activeRules.clear();
      
      console.log('[Switcher3] 清除所有插件规则');
      
      return true;
    } catch (error) {
      console.error('[Switcher3] 清除规则失败:', error);
      throw error;
    }
  }

  /**
   * 重新加载所有激活的环境
   */
  async reloadActiveEnvironments() {
    try {
      console.log('[Switcher3] 重新加载激活的环境');
      
      // 清除当前规则
      await this.clearAllRules();
      
      // 获取所有激活的环境
      const activeEnvironments = this.dataStorage.getActiveEnvironments();
      
      // 重新激活每个环境
      for (const env of activeEnvironments) {
        try {
          await this.activateEnvironment(env.projectId, env.environment);
        } catch (error) {
          console.error(`[Switcher3] 重新激活环境失败 ${env.projectId}:${env.environment}`, error);
        }
      }
      
      console.log(`[Switcher3] 重新加载完成，激活了 ${activeEnvironments.length} 个环境`);
      
      return {
        success: true,
        reloadedCount: activeEnvironments.length
      };
    } catch (error) {
      console.error('[Switcher3] 重新加载环境失败:', error);
      throw error;
    }
  }

  /**
   * 验证规则格式
   */
  validateRules(configContent) {
    if (!configContent || typeof configContent !== 'string') {
      return {
        valid: false,
        error: '配置内容不能为空'
      };
    }

    const lines = configContent.split('\n');
    const errors = [];
    
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i].trim();
      
      // 跳过空行和注释
      if (!line || line.startsWith('#')) {
        continue;
      }

      const parts = line.split(/\s+/);
      if (parts.length < 2) {
        errors.push(`第 ${i + 1} 行格式错误: ${line}`);
        continue;
      }

      const domain = parts[0];
      const target = parts[1];

      // 简单的域名格式验证
      if (!/^[a-zA-Z0-9.-]+$/.test(domain)) {
        errors.push(`第 ${i + 1} 行域名格式错误: ${domain}`);
      }

      // 简单的目标格式验证（IP或域名）
      if (!/^[a-zA-Z0-9.-:]+$/.test(target)) {
        errors.push(`第 ${i + 1} 行目标格式错误: ${target}`);
      }
    }

    if (errors.length > 0) {
      return {
        valid: false,
        error: '配置格式验证失败',
        details: errors
      };
    }

    return {
      valid: true
    };
  }

  /**
   * 获取规则统计信息
   */
  getStats() {
    const totalActiveProjects = this.activeRules.size;
    let totalRules = 0;
    
    for (const rules of this.activeRules.values()) {
      // 计算非注释和非空行的规则数量
      totalRules += rules.filter(rule => 
        rule.trim() && !rule.trim().startsWith('#')
      ).length;
    }

    return {
      activeProjects: totalActiveProjects,
      totalRules: totalRules,
      activeRulesMap: Array.from(this.activeRules.keys())
    };
  }

  /**
   * 导出当前所有规则（用于调试）
   */
  exportRules() {
    const result = {};
    
    for (const [projectId, rules] of this.activeRules.entries()) {
      const project = this.dataStorage.getProject(projectId);
      result[projectId] = {
        projectName: project ? project.name : 'Unknown',
        environment: project ? project.activeEnvironment : 'Unknown',
        rules: rules
      };
    }
    
    return result;
  }

  /**
   * 检查规则冲突（域名重复）
   */
  checkRuleConflicts() {
    const domainMap = new Map(); // domain -> [projectId, environment]
    const conflicts = [];

    for (const [projectId, rules] of this.activeRules.entries()) {
      const project = this.dataStorage.getProject(projectId);
      
      for (const rule of rules) {
        const line = rule.trim();
        if (!line || line.startsWith('#')) {
          continue;
        }

        const parts = line.split(/\s+/);
        if (parts.length >= 2) {
          const domain = parts[0];
          
          if (domainMap.has(domain)) {
            const existing = domainMap.get(domain);
            conflicts.push({
              domain: domain,
              conflicts: [
                {
                  projectId: existing.projectId,
                  projectName: existing.projectName,
                  environment: existing.environment
                },
                {
                  projectId: projectId,
                  projectName: project ? project.name : 'Unknown',
                  environment: project ? project.activeEnvironment : 'Unknown'
                }
              ]
            });
          } else {
            domainMap.set(domain, {
              projectId: projectId,
              projectName: project ? project.name : 'Unknown',
              environment: project ? project.activeEnvironment : 'Unknown'
            });
          }
        }
      }
    }

    return conflicts;
  }
}

module.exports = RuleEngine;